
package com.wk.code.wkserver.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wk.code.wkserver.constant.NumberConstant;
import com.wk.code.wkserver.entity.Permission;
import com.wk.code.wkserver.entity.Role;
import com.wk.code.wkserver.entity.RolePermission;
import com.wk.code.wkserver.exception.BizException;
import com.wk.code.wkserver.mapper.RoleMapper;
import com.wk.code.wkserver.mapper.RolePermissionMapper;
import com.wk.code.wkserver.request.admin.RoleRequest;
import com.wk.code.wkserver.response.admin.RoleListResponse;
import com.wk.code.wkserver.service.IRoleService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色服务层
 *
 * @author mjy
 * @date 2021-07-12 14:42:27
 */
@Service("roleService")
@Slf4j
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    private RolePermissionMapper rolePermissionMapper;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addRole(RoleRequest req) {
        Role role = new Role();
        role.setName(req.getName());
        role.setCode(req.getCode());
        save(role);
        savePermission(role.getId(), req.getPermissions());
    }

    @Override
    public void updateRole(RoleRequest req) {
        Role role = new Role();
        role.setName(req.getName());
        role.setCode(req.getCode());
        role.setId(req.getId());
        updateById(role);
        rolePermissionMapper.deleteByRole(req.getId());
        savePermission(req.getId(), req.getPermissions());
    }

    @Override
    public void delRole(Integer id) {
        Role role = getById(id);
        if (role.getIsDeleted().equals(NumberConstant.ONE)) {
            throw new BizException("改角色已经被删除");
        }
        baseMapper.deleteById(id);
        rolePermissionMapper.deleteByRole(id);
    }

    @Override
    public List<RoleListResponse> findRoleList() {
        List<Role> list = list();
        List<RoleListResponse> vos = new ArrayList<>();
        for (Role role : list) {
            RoleListResponse vo = new RoleListResponse();
            vo.setId(role.getId());
            vo.setCode(role.getCode());
            vo.setIsDeleted(role.getIsDeleted());
            vo.setName(role.getName());
            List<Permission> permissions = rolePermissionMapper.selectPermissions(role.getId());
            List<Integer> ids = filterPermissions(permissions);
            vo.setPermissions(ids);
            vos.add(vo);
        }
        return vos;
    }

    @Override
    public String selectRoleName(Integer roleId) {
        return baseMapper.selectById(roleId).getName();
    }

    private List<Integer> filterPermissions(List<Permission> permissions) {
        List<Integer> ids = new ArrayList<>();
        for (Permission permission : permissions) {
            if (permission.getParentId().equals(0)) {
                // 判断是否全部选择
                Integer count = rolePermissionMapper.selectCountByParent(permission.getId());
                Integer count1 = findCount(permissions, permission.getId());
                if (count.equals(count1)) {
                    ids.add(permission.getId());
                }
            } else {
                ids.add(permission.getId());
            }
        }
        return ids;
    }

    private Integer findCount(List<Permission> permissions, Integer parentId) {
        List<Permission> list = permissions.stream().filter(i -> i.getParentId().equals(parentId)).collect(Collectors.toList());
        return list.size();
    }


    private void savePermission(Integer roleId, List<Integer> permissions) {
        List<Integer> ids = new ArrayList<>();
        for (Integer permissionId : permissions) {
            ids.add(permissionId);
            Integer parentId = rolePermissionMapper.selectParentId(permissionId);
            if (!parentId.equals(0)) {
                if (!ids.contains(parentId)) {
                    ids.add(parentId);
                }
            }
        }
        for (Integer permissionId : ids) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionMapper.insert(rolePermission);
        }
    }
}
